package com.starry.module.system.core.oauth2.authorization.third.client;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.starry.module.system.core.oauth2.authorization.constant.SecurityConstants;
import com.starry.module.system.core.oauth2.authorization.third.AbstractThireClient;
import com.starry.module.system.core.oauth2.entity.Oauth2ThirdAccount;
import com.starry.module.system.core.oauth2.entity.Oauth2ThirdClient;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;

/**
 * Gitee 第三方登录
 *
 * @author xiaoke
 */
@Slf4j
public class ThireClientGitee extends AbstractThireClient {

    public ThireClientGitee(String code, Oauth2ThirdClient oauth2ThirdClient) {
        super(code, oauth2ThirdClient);
    }

    @Override
    public Oauth2ThirdAccount loadUser(String code, String state) {
        JSONObject tokenObj = getAccessToken(code);
        String accessToken = (String) tokenObj.get("access_token");
        if (accessToken == null) {
            throw new RuntimeException("获取accessToken失败");
        }

        Oauth2ThirdAccount userInfo = getUserInfo(accessToken);

        userInfo.setToken(accessToken);
        userInfo.setRawTokenInfo(JSONUtil.toJsonStr(tokenObj));
        userInfo.setTokenExpires(tokenObj.get("expires_in").toString());
        userInfo.setCode(code);
        userInfo.setState(state);
        return userInfo;
    }

    @Override
    public Oauth2ThirdClient getThirdClientConfig() {
        return thirdClientConfig;
    }


    private Oauth2ThirdAccount getUserInfo(String accessToken) {

        String userResult = HttpRequest.get(thirdClientConfig.getUserInfoUri())
                .header("Authorization", "bearer " + accessToken)
                .execute().body();

        JSON json = JSONUtil.parse(userResult);
        JSONObject userResultObj = JSONUtil.parseObj(json);

        if (userResultObj.get("id") == null) {
            throw new RuntimeException("获取用户信息失败");
        }

        Oauth2ThirdAccount thirdAccount = new Oauth2ThirdAccount();

        thirdAccount.setType(SecurityConstants.THIRD_LOGIN_GITEE);
        thirdAccount.setOpenid(userResultObj.get("id").toString());
        thirdAccount.setName((String) userResultObj.get("name"));
        thirdAccount.setAvatar((String) userResultObj.get("avatar_url"));
        thirdAccount.setUsername((String) userResultObj.get("login"));

        thirdAccount.setRawUserInfo(userResult);
        thirdAccount.setToken(accessToken);

        return thirdAccount;
    }


    private JSONObject getAccessToken(String code) {
        HashMap<String, Object> formData = new HashMap<>();
        formData.put("client_id", thirdClientConfig.getClientId());
        formData.put("client_secret", thirdClientConfig.getClientSecret());
        formData.put("redirect_uri", thirdClientConfig.getPcRedirectUrl());
        formData.put("grant_type", "authorization_code");
        formData.put("code", code);

        String tokenResult = HttpRequest.post(thirdClientConfig.getTokenUri())
                .form(formData)
                .execute().body();
        JSON json = JSONUtil.parse(tokenResult);
        return JSONUtil.parseObj(json);
    }
}
